home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / filesys / ramfs.zoo / ramfs.c < prev    next >
C/C++ Source or Header  |  1993-08-16  |  27KB  |  1,100 lines

  1. /*
  2.  * 'RAMFS': A (resizable) ramdisk file system for MiNT
  3.  * Author : Thierry Bousch
  4.  * Version: 1.4 (August 1993)
  5.  *
  6.  * Revision history:
  7.  * 1.0    Added version number, and macro-ized TRACE so that it is possible
  8.  *    to compile with or without debug information.
  9.  * 1.1  Added setuid, setgid and sticky bit for directories. Macro-ized
  10.  *      also DEBUG, ALERT and FATAL.
  11.  * 1.2  Deleted open files are now hidden. Added the valid_name() function.
  12.  *      Added a test in ram_rename about sticky directories.
  13.  * 1.3  Deleted open files are now put in a special place (the trash-list)
  14.  *      instead of leaving them half-deleted in their directories.
  15.  *      Added support for the FTRUNCATE ioctl call.
  16.  * 1.4  Take advantage of the FS_MOUNT call in MiNT 1.08, so that we can
  17.  *      get rid of drive R. Added FS_LONGPATH support.
  18.  *      The size of the RAMFILE structure is now considered in the getxattr
  19.  *      and dfree functions.
  20.  */
  21.  
  22. #include <string.h>
  23. #include "atarierr.h"
  24. #include "filesys.h"
  25.  
  26. #define VERSION  "1.4"
  27.  
  28. /*
  29.  * You may edit the following constants:
  30.  *
  31.  *    RAM_NAME    name of the ramdisk-fs directory
  32.  *    RAMFILE_MAX    maximum length of a filename
  33.  *    BLKSIZE        chunk size (must be a power of two)
  34.  *
  35.  * Define the symbols NO_{TRACE,DEBUG,ALERT,FATAL} to disable trace,
  36.  * debug, alert and fatal calls, respectively.
  37.  */
  38.  
  39. #define RAM_NAME    "U:\\ram"
  40. #define RAMFILE_MAX    35
  41. #define BLKSIZE        512L
  42. #define NO_TRACE
  43.  
  44. /*
  45.  * this points to the structure that has all the useful functions that
  46.  * the kernel told us about
  47.  */
  48.  
  49. struct kerinfo *kernel;
  50.  
  51. #define CCONWS        (*kernel->dos_tab[0x09])
  52. #define DCNTL        (*kernel->dos_tab[0x130])
  53.  
  54. #define Timestamp    (*kernel->dos_tab[0x2c])
  55. #define Datestamp    (*kernel->dos_tab[0x2a])
  56. #define FreeMemory()    (*kernel->dos_tab[0x48])(-1L)
  57. #define Getpid        (*kernel->dos_tab[0x10b])
  58. #define Getuid        (*kernel->dos_tab[0x10f])
  59. #define Getgid        (*kernel->dos_tab[0x114])
  60. #define Geteuid        (*kernel->dos_tab[0x138])
  61. #define Getegid        (*kernel->dos_tab[0x139])
  62.  
  63. #define Kmalloc        (*kernel->kmalloc)
  64. #define Kfree        (*kernel->kfree)
  65. #define Stricmp        (*kernel->stricmp)
  66. #define Denyshare    (*kernel->denyshare)
  67.  
  68. #ifndef NULL
  69. # define NULL        ((void *)0L)
  70. #endif
  71.  
  72. #define FTRUNCATE    (('F'<< 8) | 4)        /* from the Minix FS */
  73.  
  74. /* Useful macros */
  75.  
  76. #define IS_DIRECTORY(s)    (((s)->mode & S_IFMT) == S_IFDIR)
  77. #define IS_SYMLINK(s)    (((s)->mode & S_IFMT) == S_IFLNK)
  78. #define IS_SETUID(s)    ((s)->mode & S_ISUID)
  79. #define IS_SETGID(s)    ((s)->mode & S_ISGID)
  80. #define IS_STICKY(s)    ((s)->mode & S_ISVTX)
  81.  
  82. /* Conditional debugging */
  83.  
  84. #ifdef NO_DEBUG
  85. # define DEBUG(x)
  86. #else
  87. # define DEBUG(x)    (*kernel->debug)x
  88. #endif
  89.  
  90. #ifdef NO_ALERT
  91. # define ALERT(x)
  92. #else
  93. # define ALERT(x)    (*kernel->alert)x
  94. #endif
  95.  
  96. #ifdef NO_TRACE
  97. # define TRACE(x)
  98. #else
  99. # define TRACE(x)    (*kernel->trace)x
  100. #endif
  101.  
  102. #ifdef NO_FATAL
  103. # define FATAL(x)
  104. #else
  105. # define FATAL(x)    (*kernel->fatal)x
  106. #endif
  107.  
  108. /* Forward declarations of the file system functions */
  109.  
  110. long    ram_root    (int drv, fcookie *fc);
  111. long    ram_lookup    (fcookie *dir, char *name, fcookie *fc);
  112. long    ram_creat    (fcookie *dir, char *name, unsigned mode,
  113.                 int attrib, fcookie *fc);
  114. DEVDRV*    ram_getdev    (fcookie *fc, long *devsp);
  115. long    ram_getxattr    (fcookie *fc, XATTR *xattr);
  116. long    ram_chattr    (fcookie *fc, int attrib);
  117. long    ram_chown    (fcookie *fc, int uid, int gid);
  118. long    ram_chmode    (fcookie *fc, unsigned mode);
  119. long    ram_mkdir    (fcookie *fc, char *name, unsigned mode);
  120. long    ram_rmdir    (fcookie *dir, char *name);
  121. long    ram_remove    (fcookie *dir, char *name);
  122. long    ram_getname    (fcookie *root, fcookie *dir, char *path, int size);
  123. long    ram_rename    (fcookie *olddir, char *oldname,
  124.                 fcookie *newdir, char *newname);
  125. long    ram_opendir    (DIR *dirh, int flags);
  126. long    ram_readdir    (DIR *dirh, char *nm, int nmlen, fcookie *fc);
  127. long    ram_rewinddir    (DIR *dirh);
  128. long    ram_closedir     (DIR *dirh);
  129. long    ram_pathconf     (fcookie *dir, int which);
  130. long    ram_dfree    (fcookie *dir, long *buf);
  131. long    ram_writelabel    (fcookie *dir, char *name);
  132. long    ram_readlabel    (fcookie *dir, char *name, int namelen);
  133. long    ram_symlink    (fcookie *dir, char *name, char *to);
  134. long    ram_readlink    (fcookie *dir, char *buf, int len);
  135. long    ram_hardlink    (fcookie *fromdir, char *fromname,
  136.                 fcookie *todir, char *toname);
  137. long    ram_fscntl    (fcookie *dir, char *name, int cmd, long arg);
  138. long    ram_dskchng    (int drv);
  139.  
  140. /* Forward declarations of the device driver functions */
  141.  
  142. long    ram_open    (FILEPTR *f);
  143. long    ram_write    (FILEPTR *f, char *buf, long bytes);
  144. long    ram_read    (FILEPTR *f, char *buf, long bytes);
  145. long    ram_lseek    (FILEPTR *f, long where, int whence);
  146. long    ram_ioctl    (FILEPTR *f, int mode, void *buf);
  147. long    ram_datime    (FILEPTR *f, int *time, int rwflag);
  148. long    ram_close    (FILEPTR *f, int pid);
  149. long    ram_select    (FILEPTR *f, long p, int mode);
  150. void    ram_unselect    (FILEPTR *f, long p, int mode);
  151.  
  152. /* 
  153.  * Here is the structure used for ram files. The "next" field points to
  154.  * the following file/dir in that directory. The "up" field points to the 
  155.  * directory the file/dir is in, or NULL for the root directory. The
  156.  * "down" field is only used by subdirectories and points to the first
  157.  * entry in that subdirectory. "lst" is the list of open FILEPTRs for
  158.  * this file. "length" is the actual length, "data" the actual data, and
  159.  * "avail" is the length of the ram block allocated for "data".
  160.  *
  161.  * Note that all the memory is allocated in one block: it may cause trouble
  162.  * with big files if the memory is fragmented.
  163.  */
  164.  
  165. typedef struct ramfile {
  166.     struct ramfile *next, *up, *down;
  167.     char filename[RAMFILE_MAX+1];
  168.     int uid, gid;
  169.     short time, date;
  170.     unsigned mode;
  171.     FILEPTR *lst;
  172.     long length, avail;
  173.     char *data;
  174. } RAMFILE;
  175.  
  176. RAMFILE ramroot, *trash;
  177. int ram_drive;
  178.  
  179. DEVDRV ram_device = {
  180.     ram_open, ram_write, ram_read, ram_lseek, ram_ioctl, ram_datime,
  181.     ram_close, ram_select, ram_unselect
  182. };
  183.  
  184. FILESYS ram_filesys = {
  185.     (FILESYS *)0,
  186.     FS_LONGPATH,
  187.     ram_root,
  188.     ram_lookup, ram_creat, ram_getdev, ram_getxattr,
  189.     ram_chattr, ram_chown, ram_chmode,
  190.     ram_mkdir, ram_rmdir, ram_remove, ram_getname, ram_rename,
  191.     ram_opendir, ram_readdir, ram_rewinddir, ram_closedir,
  192.     ram_pathconf, ram_dfree,
  193.     ram_writelabel, ram_readlabel, ram_symlink, ram_readlink,
  194.     ram_hardlink, ram_fscntl, ram_dskchng
  195. };
  196.  
  197. struct fs_descr ram_fs_descr = { &ram_filesys };
  198.  
  199. /*
  200.  * This function is called by the kernel when the
  201.  * file system is being loaded, and should return the file system
  202.  * structure
  203.  */
  204.  
  205. FILESYS *ram_init (struct kerinfo *k)
  206. {
  207.     kernel = k;
  208.  
  209.     CCONWS("Ramdisk filesystem for MiNT (Version " VERSION ", compiled " 
  210.     __DATE__ ") by T.Bousch\r\n");
  211.  
  212.     TRACE(("ram_init: initialize filesystem"));
  213.     ramroot.next = ramroot.up = ramroot.down = NULL;
  214.     ramroot.filename[0] = 0;
  215.     ramroot.uid  = ramroot.gid = 0;
  216.     ramroot.time = Timestamp();
  217.     ramroot.date = Datestamp();
  218.     ramroot.mode = S_IFDIR | DEFAULT_DIRMODE;
  219.     ramroot.lst  = NULL;
  220.     ramroot.length = ramroot.avail = 0;
  221.     ramroot.data = NULL;
  222.     trash = NULL;
  223.  
  224.     /* 
  225.      * We try first to install the filesystem as a gemdos-only drive
  226.      * because we don't want to pollute the bios drive map with a fake
  227.      * drive. Unfortunately, this will only work with recent MiNT
  228.      * versions (at least 1.08); with older versions we fallback
  229.      * to the previous method (install drive 'R').
  230.      */
  231.     if (DCNTL(FS_INSTALL, RAM_NAME, &ram_fs_descr) >= 0 &&
  232.         DCNTL(FS_MOUNT,   RAM_NAME, &ram_fs_descr) >= 0) {
  233.         ram_drive = ram_fs_descr.dev_no;
  234.         /* Tell the kernel that the filesystem is already loaded */
  235.         return (FILESYS*)(1L);
  236.     }
  237.     /* Add drive 'R' to the list of Bios drives */
  238.     ram_drive = 'R'-'A';
  239.     *(unsigned long *)(0x4c2L) |= (1UL << ram_drive);
  240.     return &ram_filesys;
  241. }
  242.  
  243. long ram_root (int drv, fcookie *fc)
  244. {
  245.     if (drv == ram_drive) {
  246.         TRACE(("ram_root: drive #%d is a ramdisk", drv));
  247.         fc->fs = &ram_filesys;
  248.         fc->dev = drv;
  249.         fc->index = (long) &ramroot;
  250.         return 0;
  251.     } else {
  252.         fc->fs = NULL;    /* Not our drive */
  253.         return EDRIVE;
  254.     }
  255. }
  256.  
  257. long ram_lookup (fcookie *dir, char *name, fcookie *fc)
  258. {
  259.     RAMFILE *s, *d;
  260.     
  261.     TRACE(("ram